package com.color.admin.auth.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.color.admin.auth.entity.LoginDto;
import com.color.admin.auth.service.AuthService;
import com.color.admin.auth.service.CaptchaService;
import com.color.admin.common.core.constant.Constant;
import com.color.admin.common.core.exception.BaseException;
import com.color.admin.common.core.result.ResultCode;
import com.color.admin.common.core.result.ResultData;
import com.color.admin.common.core.utils.cache.RedisUtils;
import com.color.admin.common.core.utils.web.ServletUtils;
import com.color.admin.common.core.utils.web.ToolUtils;
import com.color.admin.system.controller.UserController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Map;

/**
 * @author HaiQiu
 * @date 2021/12/15
 */
@Service
public class AuthServiceImpl implements AuthService {

    @Autowired
    private UserController userController;

    @Autowired
    private CaptchaService captchaService;


    @Autowired
    private RedisUtils redisUtils;


    @Override
    public Map<String, Object> login(LoginDto loginDto) {
        safeVerify(loginDto);
        if (!StringUtils.hasText(loginDto.getCaptcha())) {
            throw new BaseException("验证码为空");
        }
        captchaService.checkCaptcha(loginDto.getCaptcha());
        ResultData result = null;
        try{
            result = userController.login(loginDto);
        }catch (Exception e){
            throw new BaseException(e.getMessage());
        }finally {
            safeLogin(loginDto);
        }

        Map<String, Object> map = JSONObject.parseObject(JSON.toJSONString(result.getData()));
        return map;
    }

    @Override
    public void loginOut(String userId) {
        userId = ServletUtils.getUserId() == null ? userId : ServletUtils.getUserId();
        redisUtils.clearRedis(RedisUtils.clearType.USER_AUTH, userId);
        redisUtils.clearRedis(RedisUtils.clearType.USER_INFO, userId);
        redisUtils.del(Constant.USER_SECURITY + ServletUtils.getUsername());
    }


    public void safeLogin(LoginDto loginDto) {
        int count = getCacheErrorCount(loginDto);
        count++;
        redisUtils.set(getUserKey(loginDto), String.valueOf(count), 15 * 60L);
    }

    public void safeVerify(LoginDto loginDto) {
        int count = getCacheErrorCount(loginDto);
        Long expireTime = redisUtils.getExpireTime(getUserKey(loginDto));
        if (count > 5) {
            if (expireTime != -1 && expireTime != -2) {
                System.out.println(expireTime);
                Long expire;
                String unit = "分钟";
                if (expireTime>60){
                    expire = expireTime/60;
                }else {
                    expire = expireTime;
                    unit = "秒";
                }
                throw new BaseException(ResultCode.LOGIN_ERROR.getCode(), "你已经连续" +
                        count + "次登录失败，已冻结15分钟，大约剩余：" + expire + unit);
            }
            throw new BaseException(ResultCode.LOGIN_ERROR.getCode(), "你已经连续" + count + "次登录失败，已冻结15分钟");
        }
    }


    private int getCacheErrorCount(LoginDto loginDto) {
        getUserKey(loginDto);
        int i;
        if (redisUtils.get(getUserKey(loginDto)) == null) {
            i = 0;
        } else {
            String count = (String) redisUtils.get(getUserKey(loginDto));
            i = Integer.parseInt(count);
        }
        return i;
    }

    private String getUserKey(LoginDto loginDto) {
        String ip = ToolUtils.getIp();
        String user = loginDto.getUsername() + "." + ip;
        return Constant.USER_LOGIN_ERROR + user;
    }
}
